package com.ecoolex.hotel.saas.api.graphql;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.ecoolex.framework.modularize.api.auth.user.ConsumerMember;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberManager;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.io.HttpUtil;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberAuthority;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrder;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderAfterSales;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderDetail;
import com.ecoolex.hotel.saas.entity.StoreOrderConfig;
import com.ecoolex.hotel.saas.enums.PresaleCouponOrderStatus;
import com.ecoolex.hotel.saas.pojo.SubmitPresaleCouponOrderDTO;
import com.ecoolex.hotel.saas.ws.PaymentOrderService;
import com.ecoolex.hotel.saas.ws.PresaleCouponOrderService;
import com.ecoolex.hotel.saas.ws.StoreService;

@GraphQL2Module(type = Type.User, description = "预售券订单")
public class PresaleCouponOrderGraphql {

	@Reference
	private PresaleCouponOrderService presaleCouponOrderService;
	
	@Reference
	private PaymentOrderService paymentOrderService;
	
	@Autowired
	private StorageService storageService;
	
	@Reference
	private StoreService storeService;

	@TypeField(type = PresaleCouponOrder.class, field = "cancelTimeValue", description = "自动取消时间（值）")
	public Integer cancelTime(@Source PresaleCouponOrder source) {
		StoreOrderConfig config = storeService.getStoreOrderConfig(source.getStoreId());
		if(Check.notNull(config)) {
			return config.getAutoCancelTime();
		}else {
			return null;
		}
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "canPay", description = "能支付")
	public Boolean canPay(@Source PresaleCouponOrder source) {
		return PresaleCouponOrderStatus.canPay(source.getStatus());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "canRefund", description = "能退款")
	public Boolean canRefund(@Source PresaleCouponOrder source) {
		return PresaleCouponOrderStatus.canRefund(source.getStatus()) && 
			presaleCouponOrderService.presaleCouponCanRefund(source.getOrderId());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "canCancel", description = "能取消")
	public Boolean canCancel(@Source PresaleCouponOrder source) {
		return PresaleCouponOrderStatus.canCancel(source.getStatus());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "canDel", description = "能删除")
	public Boolean canDel(@Source PresaleCouponOrder source) {
		return PresaleCouponOrderStatus.canDel(source.getStatus());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "presaleCouponOrderDetail", description = "订单明细")
	public List<PresaleCouponOrderDetail> presaleCouponOrderDetail(@Source PresaleCouponOrder source){
		return presaleCouponOrderService.queryOrderDetail(source.getOrderId());
	}
	
	@TypeField(type = PresaleCouponOrderDetail.class, field = "coverImage", description = "订单明细商品封面图")
	public StorageInfo coverImage(@Source PresaleCouponOrderDetail source) {
		return storageService.get(source.getCoverImage());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "lastestPresaleCouponOrderAfterSales", description = "订单关联的最新一条售后单")
	public PresaleCouponOrderAfterSales lastestAfterSales(@Source PresaleCouponOrder source) {
		return presaleCouponOrderService.getLastestByOrderId(source.getOrderId());
	}
	
	@QueryField(field = "presaleCouponOrder", description = "预售券订单详情")
	public PresaleCouponOrder get(@NonNull Integer orderId, ConsumerMemberAuthority user) {
		user.assertLogin();
		return presaleCouponOrderService.getForUser(orderId, user.userId());
	}
	
	@QueryField(field = "presaleCouponOrderList", description = "预售券订单列表")
	public Pagination<PresaleCouponOrder> query(@NonNull Integer storeId, Integer status,@NonNull Page page, ConsumerMemberAuthority user){
		user.assertLogin();
		return presaleCouponOrderService.queryForUser(storeId, status, user.userId(), page);
	}
	
	@MutationField(field = "submitPresaleCouponOrder", description = "提交预售券订单")
	public PresaleCouponOrder submit(@NonNull SubmitPresaleCouponOrderDTO submit, ConsumerMemberAuthority user) {
		user.assertLogin();
		submit.setUserId(user.userId());
		submit.setUserName(user.userName());
		return presaleCouponOrderService.submit(submit, user.userName());
	}
	
	@MutationField(field = "applyWechatPayPresaleCouponOrder", description = "发起预售券订单微信支付")
	public Map wechatPay(@NonNull String appId, @NonNull Integer orderId, HttpServletRequest request, ConsumerMemberAuthority user) {
		user.assertLogin();
		PresaleCouponOrder order = presaleCouponOrderService.getForUser(orderId, user.userId());
		Assert.isTrue(Check.notNull(order),ResultCode.VERIFY.build(1), "订单不存在");
		Assert.isTrue(PresaleCouponOrderStatus.canPay(order.getStatus()),ResultCode.VERIFY.build(2), "订单无法发起支付");
		Map result = paymentOrderService.weChatPayApply(order, appId, HttpUtil.getIpAddr(request), user.userName());
		Assert.isTrue(Check.notNull(result),ResultCode.VERIFY.build(3),"发起支付失败");
		return result;
	}

	@MutationField(field = "applyOfflinePayPresaleCouponOrder", description = "发起预售券订单线下支付")
	public PresaleCouponOrder offlinePay(@NonNull Integer orderId, ConsumerMemberAuthority user){
		user.assertLogin();
		PresaleCouponOrder order = presaleCouponOrderService.getForUser(orderId, user.userId());
		Assert.isTrue(Check.notNull(order),ResultCode.VERIFY.build(1), "订单不存在");
		Assert.isTrue(PresaleCouponOrderStatus.canPay(order.getStatus()),ResultCode.VERIFY.build(2), "订单无法发起支付");
		return presaleCouponOrderService.applyOfflinePay(order,user.userName());
	}
	
	@MutationField(field = "applyPresaleCouponOrderRefund", description = "发起预售券订单退款")
	public PresaleCouponOrder refund(@NonNull Integer orderId,String remark, String evidenceImage, ConsumerMemberAuthority user) {
		user.assertLogin();
		PresaleCouponOrder order = presaleCouponOrderService.getForUser(orderId, user.userId());
		Assert.isTrue(Check.notNull(order),ResultCode.VERIFY.build(1), "订单不存在");
		return presaleCouponOrderService.applyRefund(order, remark, evidenceImage, user.userName());
	}
	
	@MutationField(field = "cancelPresaleCouponOrder", description = "取消预售券订单")
	public PresaleCouponOrder cancel(@NonNull Integer orderId, ConsumerMemberAuthority user) {
		user.assertLogin();
		PresaleCouponOrder order = presaleCouponOrderService.getForUser(orderId, user.userId());
		Assert.isTrue(Check.notNull(order),ResultCode.VERIFY.build(1), "订单不存在");
		return presaleCouponOrderService.cancel(order, user.userName());
	}
	
	@MutationField(field = "delPresaleCouponOrder", description = "删除预售券订单")
	public PresaleCouponOrder del(@NonNull Integer orderId, ConsumerMemberAuthority user) {
		user.assertLogin();
		PresaleCouponOrder order = presaleCouponOrderService.getForUser(orderId, user.userId());
		Assert.isTrue(Check.notNull(order),ResultCode.VERIFY.build(1), "订单不存在");
		return presaleCouponOrderService.delete(order, user.userName());
	}
	
	@MutationField(field = "uploadEvidenceImage", description = { "上传售后凭证图片" })
	public StorageInfo uploadGoodsBrandLogo(@NonNull Upload request) {
        UploadSource uploadSource = new UploadSource("PresaleCouponOrderAfterSales", "EvidenceImage");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}
}
